A portfolio is a collection of financial investments like stocks, bonds, commodities, cash, and cash equivalents, including closed-end funds and exchange-traded funds (ETFs). One of the key concepts in portfolio management is the wisdom of diversification—which simply means not to put all your eggs in one basket. Diversification tries to reduce risk by allocating investments among various financial instruments, industries, and other categories. It aims to maximize returns by investing in different areas that would each react differently to the same event.
Ex) Portfolio consists of two stock items \[R_{p}=W_{1}R_{1}+W_{2}R_{2} (단, W_{1}+W_{2}=1)\] \[E(R_{p})=W_{1}\mu_{1}+W_{2}\mu_{2}\] \[Var(R_{p})=W_{1}^2\sigma_{1}^2+W_{2}^2\sigma_{2}^2+2W_{1}W_{2}\rho\sigma_{1}\sigma_{2}\]
Portfolio Effect : An effect that occurs when you build a portfolio by collecting two or more of financial investments. Risk of each financial investment is offset by risk of other financial investments in a portfolio.
setwd('C:\\Users\\sungi\\Documents\\GitHub\\Financial-Data-Analysis-Stock-Portfolio\\data')
AAN<-read.csv("AAN(Aaron's_Inc).csv")
ATU<-read.csv("ATU(Actuant_Corp).csv")
ASE<-read.csv("ASE(Advanced_Semiconductor_Engineering_Inc.).csv")
IBM<-read.csv("IBM(International_Business_Machines).csv")
XOM<-read.csv("XOM(Exxon_Mobile_corp).csv")
dat.BM <- read.csv('NYSE2.csv')
AANc<-AAN[,5]
ATUc<-ATU[,5]
ASEc<-ASE[,5]
IBMc<-IBM[,5]
XOMc<-XOM[,5]
BM<-dat.BM[,5]/100
day<-as.factor(AAN[,1])
dat<-data.frame(day,AANc,ATUc,ASEc,IBMc,XOMc,BM)
colnames(dat)<-c("Date","AAN","ATU","ASE","IBM","XOM","BM")
head(dat)
## Date AAN ATU ASE IBM XOM BM
## 1 2015-12-01 22.39 23.96 5.67 137.62 77.95 101.4342
## 2 2015-11-02 24.27 24.76 5.39 139.42 81.66 104.0959
## 3 2015-10-01 24.67 22.80 5.74 140.08 82.74 104.6096
## 4 2015-09-01 36.11 18.39 5.49 144.97 74.35 97.9969
## 5 2015-08-03 37.65 21.44 4.92 147.89 75.24 101.7650
## 6 2015-07-01 36.98 23.06 5.60 161.99 79.21 108.8228
datm<-as.matrix(dat[,-c(1,7)])
head(datm)
## AAN ATU ASE IBM XOM
## [1,] 22.39 23.96 5.67 137.62 77.95
## [2,] 24.27 24.76 5.39 139.42 81.66
## [3,] 24.67 22.80 5.74 140.08 82.74
## [4,] 36.11 18.39 5.49 144.97 74.35
## [5,] 37.65 21.44 4.92 147.89 75.24
## [6,] 36.98 23.06 5.60 161.99 79.21
Plot of the price of each stock item.
NYSE index has a much higher price compared to other stock items. To see the whole trend of each stock price more easily, we divided each stock price by 100.
library(ggplot2)
library(reshape)
library(plotly)
library(grid)
library(gridExtra)
p <- plot_ly(dat, x = ~Date, y = ~AAN, name="AAN", type='scatter',mode='lines')
p %>% add_trace(y = ~ATU, x = ~Date, name="ATU") %>%
add_trace(y = ~ASE,x= ~Date, name="ASE") %>%
add_trace(y = ~IBM, x = ~Date, name="IBM") %>%
add_trace(y = ~XOM, x = ~Date, name="XOM") %>%
add_trace(y = ~BM, x = ~Date, name="NYSE") %>%
layout(title = "Stock Price Plot",yaxis=list(title="Price"),showlegend = TRUE)
## Warning: `arrange_()` is deprecated as of dplyr 0.7.0.
## Please use `arrange()` instead.
## See vignette('programming') for more help
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
basket<-1:5
dat.diff <- diff(datm)
Returns <- dat.diff/datm[-nrow(datm),]
Returnsn<-data.frame(index=1:nrow(Returns),Returns)
head(Returns)
## AAN ATU ASE IBM XOM
## [1,] 0.08396610 0.033389025 -0.04938272 0.013079517 0.04759470
## [2,] 0.01648125 -0.079159976 0.06493506 0.004733926 0.01322550
## [3,] 0.46372116 -0.193421061 -0.04355401 0.034908616 -0.10140198
## [4,] 0.04264749 0.165851124 -0.10382514 0.020142084 0.01197041
## [5,] -0.01779554 0.075559605 0.13821138 0.095341173 0.05276450
## [6,] -0.02082209 0.001300997 0.17857143 0.004136051 0.05037240
p <- plot_ly(Returnsn, x=~index, y = ~AAN, name="AAN", type='scatter', mode='lines')
p %>% add_trace(x=~index,y = ~ATU, name="ATU") %>%
add_trace(x=~index, y = ~ASE, name="ASE") %>%
add_trace(x=~index,y = ~IBM, name="IBM") %>%
add_trace(x=~index, y = ~XOM, name="XOM") %>%
layout(title = "Return Plot",yaxis=list(title="Return"),showlegend = TRUE)
To minimize \({\mathbf{w'}} {\mathbf{\Sigma}} {\mathbf{w}}\) subject to \({\mathbf{w'}} {\mathbf{\mu}}\) = \(\mu_{p}\), \({\mathbf{w'}} {\mathbf{1}}\) = 1. \[ \large{{\mathbf{w_{p}}} = {\mathbf{g}} + {\mathbf{h}} \mu_{p}} \] \({\mathbf{g}} = \frac{B({\mathbf{\Sigma^{-1}}} {\mathbf{1}}) - A({\mathbf{\Sigma^{-1}}} {\mathbf{\mu}})}{D}\) \({\mathbf{h}} = \frac{C({\mathbf{\Sigma^{-1}}} {\mathbf{\mu}}) - A({\mathbf{\Sigma^{-1}}} {\mathbf{1}})}{D}\) \(A = {\mathbf{1'}} \Sigma^{-1} {\mathbf{\mu}}\), \(B = {\mathbf{\mu'}} \Sigma^{-1} {\mathbf{\mu}}\), \(C = {\mathbf{1'}} \Sigma^{-1} {\mathbf{1}}\), \(D = BC - A^{2}\)
MVP function
mu.p <- seq(from=0, to=0.05, length=21)
res.mvp <- Minimum.variance.portfolio(Returns=Returns[,basket],
mu.p=seq(from=0, to=0.05, length=50),
do.plot=T, prt=F)
## Min.sigma.p Min.mu.p
## 0.033446029 0.003061224
MVP.prediction <- Minimum.variance.portfolio(Returns=Returns[,basket],
mu.p=c(0.005,0.01),
do.plot=F, prt=F)$w.p
colnames(MVP.prediction) <- c("ERR: 0.005", "ERR: 0.01")
MVP.prediction
## ERR: 0.005 ERR: 0.01
## AAN 0.1224416 0.1420905
## ATU 0.3703707 1.1736297
## ASE 0.2139527 0.3670784
## IBM 0.6984054 1.4655150
## XOM -0.4051705 -2.1483137
To minimize \({\mathbf{w'}} {\mathbf{\Sigma}} {\mathbf{w}}\) subject to \({\mathbf{w'}}\)\({\mathbf{\mu}}\) + \((1- {\mathbf{w'}} {\mathbf{1}})\)\(R_{f}\) = \(\mu_{p}\). \[ {\mathbf{w_{q}}} = \frac{{\mathbf{w_{p}}}}{{\mathbf{1'}} {\mathbf{w_{p}}}} = \frac{c_{p} {\mathbf{\bar{w}}}}{c_{p} {\mathbf{1'}} {\mathbf{\bar{w}}}} = \frac{1}{{\mathbf{1'}} {\mathbf{\Sigma^{-1}}} ({\mathbf{\mu}} - R_{f} {\mathbf{1}})} · {\mathbf{\Sigma^{-1}}} ({\mathbf{\mu}} - R_{f} {\mathbf{1}}) \]
Tangency function
Tangency.portfolio <- function(Returns, r.f, do.plot=F)
{
mu <- apply(Returns, 2, mean)
Sigma <- cov(Returns)
Sigma.inv <- solve(Sigma)
ones <- rep(1, dim(Returns)[2])
tmp <- mu-r.f*ones
w.bar <- Sigma.inv%*%tmp
w.q <- w.bar/sum(w.bar)
mu.q <- crossprod(w.q, mu)
sigma.q <- sqrt((t(w.q)%*%Sigma%*%w.q)[1,1])
lb <- max(0, mean(mu)-0.025)
ub <- max(mu)+0.025
mvp <- Minimum.variance.portfolio(Returns, mu.p=seq(from=lb, to=ub, len=21), do.plot=do.plot, prt=F)
if (do.plot) {
slope <- (mu.q-r.f)/sigma.q
abline(r.f, slope, col=3)
points(sigma.q, mu.q, pch=17, col=2)
}
return(list(mu.q=mu.q, sigma.q=sigma.q, w.q=w.q))
}
\[{r.f} =\frac{CD}{{12}*{100}} = {0.0013}\]
res.tan <- Tangency.portfolio(Returns[,basket], r.f=0.0013, do.plot=T)
res.tan
## $mu.q
## [,1]
## [1,] 0.006542412
##
## $sigma.q
## [1] 0.06127035
##
## $w.q
## [,1]
## AAN 0.1285030
## ATU 0.6181620
## ASE 0.2611893
## IBM 0.9350452
## XOM -0.9428994
CAPM Model(Capital Asset Pricing Model)
Capital Market Line :
\[\mu_{p}=R_{f}+\frac{\mu_{A}-R_{f}}{\sigma_{A}}\sigma_{p}\]
Capital asset pricing model (CAPM), depicts the trade-off between risk and return for efficient portfolios. It is a theoretical concept that represents all the portfolios that optimally combine the risk-free rate of return and the market portfolio of risky assets.
SCL(Security Characteristic Line) \[R_{i}=\alpha_{i}+\beta_{i}R_{m}\]
Equilibrium & SML(Security market Line) \[\frac{E(R_{m})-R_{f}}{\sigma_{m}}=\frac{E(R_{i})-R_{f}}{\sigma_{im}}\]
CAPM function
CAPM.measures <- function(R.p, R.BM, r.f, do.plot=T)
{
x <- R.BM - r.f
y <- R.p - r.f
res.lm <- lm(y~x)
plot(x, y, xlab='Benchmark', ylab='Portfolio')
abline(res.lm$coef, col=2, lwd=2)
abline(v=0, lty=2)
abline(h=0, lty=2)
expected.excess.return <- mean(y)
vol <- sd(y)
alpha <- res.lm$coef[1]
beta <- res.lm$coef[2]
Sharpe <- expected.excess.return/vol
Treynor <- expected.excess.return/beta
return(list(Expected.excess.return=expected.excess.return,
Volatility=vol,
Jensen.alpha=alpha,
Beta=beta,
Sharpe=Sharpe,
Treynor=Treynor))
}
Expected excess return
Volatility
Jensen’s alpha
Beta
\[\beta=\frac{\sigma_{im}}{\sigma_{m^2}}\]
Treynor ratio
\[\frac{\mu_{p} - R_{f}}{\beta_{p}}\]
dat.BM <- as.matrix(dat.BM[,-1])
BM.diff <- diff(dat.BM)
R.BM <- BM.diff/dat.BM[-nrow(dat.BM),]
head(R.BM)
## Open High Low Close Volume
## [1,] 0.002634283 0.011196544 0.026429027 0.026240649 0.02166620
## [2,] -0.061315107 -0.009716602 -0.043807927 0.004934884 0.02185005
## [3,] 0.035003902 -0.016697314 -0.013615100 -0.063213083 -0.01733789
## [4,] 0.069470813 0.053459378 -0.005817981 0.038451171 0.04765398
## [5,] -0.003584313 0.010662173 0.117011405 0.069353930 -0.12027231
## [6,] 0.021873838 0.012527403 0.013772867 -0.007083081 -0.05307191
## Adj.Close
## [1,] 0.026240649
## [2,] 0.004934884
## [3,] -0.063213083
## [4,] 0.038451171
## [5,] 0.069353930
## [6,] -0.007083081
## Jensen_Alpha Beta
## Tangency 0.0085 0.7460
## MVP 0.0047 0.6790
## Same 0.0053 0.7619
## Jensen_Alpha Beta
## AAN 0.0021 0.3484
## ATU 0.0095 1.3029
## ASE 0.0061 0.7806
## IBM 0.0048 0.5276
## XOM 0.0039 0.8503
| Tangency | MVP | Same | AAN | ATU | ASE | IBM | XOM | |
|---|---|---|---|---|---|---|---|---|
| Expected Excess Return | 0.0052 | 0.0018 | 0.002 | 0.0005 | 0.0039 | 0.0027 | 0.0025 | 0.0002 |
| Volatility | 0.0613 | 0.0334 | 0.0367 | 0.1006 | 0.0743 | 0.0747 | 0.0455 | 0.044 |
| Jensen Alpha | 0.0085 | 0.0047 | 0.0053 | 0.0021 | 0.0095 | 0.0061 | 0.0048 | 0.0039 |
| Beta | 0.7456 | 0.6791 | 0.7619 | 0.3484 | 1.3029 | 0.7806 | 0.5276 | 0.8503 |
| Sharpe | 0.0856 | 0.0527 | 0.0536 | 0.0055 | 0.0518 | 0.0363 | 0.0541 | 0.0053 |
| Treynor | 0.007 | 0.0026 | 0.0026 | 0.0016 | 0.003 | 0.0035 | 0.0047 | 0.0002 |
CAPM<-data.frame(expect.r,vol,alpha,beta,sharpe,treynor,name)
colnames(CAPM)<-c("Expected.excess.return",
"Volatility","Jensen.alpha","Beta",
"Sharpe","Treynor","Portfolio.name")
CAPM
## Expected.excess.return Volatility Jensen.alpha Beta Sharpe
## 1 0.0052424118 0.06127035 0.008492308 0.7456456 0.085561976
## 2 0.0019627466 0.03665043 0.005283638 0.7619345 0.053553165
## 3 0.0017612245 0.03344603 0.004721250 0.6791387 0.052658702
## 4 0.0005499687 0.10060481 0.002068381 0.3483796 0.005466624
## 5 0.0038511703 0.07427546 0.009529783 1.3028825 0.051849836
## 6 0.0027126135 0.07470554 0.006114790 0.7805842 0.036310739
## 7 0.0024646076 0.04553918 0.004764043 0.5275749 0.054120596
## 8 0.0002353729 0.04403471 0.003941192 0.8502511 0.005345166
## Treynor Portfolio.name
## 1 0.0070307018 Tangency
## 2 0.0025760044 Same
## 3 0.0025933206 Mvp
## 4 0.0015786476 AAN
## 5 0.0029558846 ATU
## 6 0.0034751066 ASE
## 7 0.0046715785 IBM
## 8 0.0002768275 XOM
CAPM.m<-melt(CAPM,id=c("Portfolio.name"))
head(CAPM.m)
## Portfolio.name variable value
## 1 Tangency Expected.excess.return 0.0052424118
## 2 Same Expected.excess.return 0.0019627466
## 3 Mvp Expected.excess.return 0.0017612245
## 4 AAN Expected.excess.return 0.0005499687
## 5 ATU Expected.excess.return 0.0038511703
## 6 ASE Expected.excess.return 0.0027126135
Expected Excess Return
Jensen’s alpha
Volatility
Beta
## null device
## 1
setwd('C:\\Users\\sungi\\Documents\\GitHub\\Financial-Data-Analysis-Stock-Portfolio\\data')
AAN16<-read.csv("AAN(2016).csv")
ATU16<-read.csv("ATU(2016).csv")
ASE16<-read.csv("ASE(2016).csv")
IBM16<-read.csv("IBM(2016).csv")
XOM16<-read.csv("XOM(2016).csv")
p16<-data.frame(AAN16[,5],ATU16[,5],ASE16[,5],IBM16[,5],XOM16[,5])
colnames(p16)<-c("AAN","ATU","ASE","IBM","XOM")
p16[1:5,]<-p16[5:1,]
rownames(p16)<-c("Dec","Jan","Feb","Mar","Apr")
dat16<-as.matrix(p16)
diff16 <- diff(dat16)
Returns16 <- diff16/dat16[-nrow(dat16),]
rownames(Returns16)<-c("Jan","Feb","Mar","Apr")
Returns16
## Jan Feb Mar Apr
## -0.11543486 0.03615016 0.16206149 -0.06470580
## Jan Feb Mar Apr
## -0.01429559 0.03699036 0.06382549 0.01715929
## Jan Feb Mar Apr
## -0.031488744 0.028081442 0.077399538 0.004649254
## Jan Feb Mar Apr
## 0.021884771 0.004807736 0.091779034 0.044223068
## Jan Feb Mar Apr
## -0.028380552 0.005584149 0.055531781 0.080938894
## Jan Feb Mar Apr
## -0.05643739 0.05046729 0.04092527 -0.12307692
## Jan Feb Mar Apr
## -0.09322769 0.05000399 0.15584216 -0.03638161
## Jan Feb Mar Apr
## -0.001282861 0.029544047 0.042919450 0.057542843
## tan mvp same AAN ATU ASE
## Jan -0.11543486 -0.01429559 -0.031488744 0.021884771 -0.028380552 -0.05643739
## Feb 0.03615016 0.03699036 0.028081442 0.004807736 0.005584149 0.05046729
## Mar 0.16206149 0.06382549 0.077399538 0.091779034 0.055531781 0.04092527
## Apr -0.06470580 0.01715929 0.004649254 0.044223068 0.080938894 -0.12307692
## IBM XOM
## Jan -0.09322769 -0.001282861
## Feb 0.05000399 0.029544047
## Mar 0.15584216 0.042919450
## Apr -0.03638161 0.057542843
## [,1]
## AAN 0.1285030
## ATU 0.6181620
## ASE 0.2611893
## IBM 0.9350452
## XOM -0.9428994
Aggregational Gaussian
## null device
## 1
## Volatility Expected_returns
## Tangency 0.06127035 0.006542412
## MVP 0.03344603 0.003061224
## Same 0.03665043 0.003262747
## AAN 0.10060481 0.001849969
## ATU 0.07427546 0.005151170
## ASE 0.07470554 0.004012613
## IBM 0.04553918 0.003764608
## XOM 0.04403471 0.001535373
The portfolio with the highest expected rate of return is Tangency portfolio.
The portfolios with the lowest volatility are MVP and Same portfolios. However, they have the expected rate of return that is only a half of Tangency portfolio.
Therefore, if you want a portfolio with the highest expected rate of return, choose Tangency portfolio. If you want a portfolio with the lowest volatility, choose MVP or Same portfolio.